//    Copyright (C) Kherty.  All rights reserved.
using System;
using System.ComponentModel;
using System.Diagnostics.Contracts;
using System.Reflection;
using System.Windows.Controls;
using OpenLS.Chart;
using OpenLS.Core.Serialization;
using OpenLS.Drawing;
using OpenLS.Spreadsheet.Internals;
using OpenLS.Spreadsheet.Serialization;

namespace OpenLS.Spreadsheet.Drawing
{
    public abstract class Anchor : IOfficeXmlSerializable, INotifyPropertyChanged
    {
        protected Anchor(Worksheet ws)
        {
            _worksheet = ws;
        }
        internal static IAnchored ReadContent(ReadContext context)
        {
            switch (context.ReaderLocalName)
            {
                case null:
                    return null;
                case "graphicFrame":
                    return context.ReadElement<GraphicFrame>();
                case "pic":
                    var spreadsheetContext = context.GetData<SpreadsheetContext>();
                    return XamlElement.FromPicture(context.ReadElement<Picture>(), spreadsheetContext != null?spreadsheetContext.XamlElementResolver:null);
                case "sp":
                    return context.ReadElement<Shape>();
                case "grpSp":
                    return context.ReadElement<GroupShape>();
                case "cxnSp":
                    return context.ReadElement<Connector>();
                default: throw new NotSupportedException();
            }
        }
        

        #region IOfficeXmlSerializable Members

        void IOfficeXmlSerializable.ReadXml(ReadContext context)
        {
            ReadXmlCore(context);
        }

        void IOfficeXmlSerializable.WriteXml(WriteContext context)
        {
            WriteXmlCore(context);
        }
        internal abstract void ReadXmlCore(ReadContext context);

        internal abstract void WriteXmlCore(WriteContext context);

        #endregion

        public abstract double ActualWidth { get;set;}
        public abstract double ActualHeight { get;set;}
        public abstract double RowOffset { get;set;}
        public abstract double ColumnOffset { get;set;}
        IAnchored _content;
        public IAnchored Content { get { return _content; } set
        {
            Contract.Requires(value != null);
            _content = value; NotifyPropertyChanged("Content");
        } }
        private AnchorClientData _clientData;

        public AnchorClientData ClientData
        {
            get {if (_clientData == null)
                _clientData = new AnchorClientData();
                return _clientData; }
            set { _clientData = value; }
        }

        #region INotifyPropertyChanged Members

        public event PropertyChangedEventHandler PropertyChanged;



        protected void NotifyPropertyChanged(string propertyName)
        {
            Contract.Requires(GetType().GetProperty(propertyName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic) != null);
            if (PropertyChanged != null)
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }

        #endregion

        internal void DragSide(double amount, Dock sideType)
        {
            if (Worksheet.Workbook.UndoEnabled)
                Worksheet.Workbook.AddUndoUnit(new DraggedAnchorSideUndoUnit(this, amount, sideType));
            DragSideImp(amount, sideType);
        }

        internal abstract void DragSideImp(double amount, Dock type);

        internal  void Drag(double x, double y)
        {
            //using (Worksheet.Workbook.CreateUndoScope(StringTable.Anchor)) 
            {
                if (Worksheet.Workbook.UndoEnabled)
                    Worksheet.Workbook.AddUndoUnit(new DraggedAnchorUndoUnit(this, x, y));
                DragImp(x, y);
            }
        }

        internal abstract void DragImp(double x, double y);
        private readonly Worksheet _worksheet;

        public Worksheet Worksheet
        {
            get { return _worksheet; }
        }
	
        
    }
}